package {
	import cmodule.b.CLibInit;
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.utils.ByteArray;
	import net.NetClient;
	import net.NetManager;
	
	import flash.display.Shape;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.text.TextField;
	import flash.utils.getTimer;
	
	import mx.core.UIComponent;
	
	import view.bushuai.map.MapInfo;
	import view.bushuai.map.box.Pan_Tile;
 
	import flash.events.*;
	import flash.net.ObjectEncoding;
	import flash.net.Socket;
	
	import flash.utils.ByteArray; 
	import flash.net.URLLoaderDataFormat;
	import net.MessageBase;
	
	public class map extends UIComponent 
	{
		private var loader:CLibInit=new CLibInit();
		private var lib:Object=loader.init();
		private var pan_tile:Pan_Tile;
		//private var start_pt:int, end_pt:int;
		//private var path_sp:Shape = new Shape();
		private var mapdt:String="";
		private var txt:TextField = new TextField();
		private var txt1:TextField = new TextField();
		//private var socket :Socket;
		
		private var ActorList:Array;
		private var SelfActor:ActorInfo ;
		private var LastEnterFrame:Number;
		private var _loader:Loader;    //装载	
		private static var instance:map;
		
		public function map()
		{
			_loader = new Loader();
			ActorList = new Array();
			
			txt1.mouseEnabled = false;
			txt1.x = 0;
			txt1.y = 800;
			txt1.background = true;
			txt1.autoSize = "left";
			txt1.backgroundColor = 0x0;
			txt1.textColor = 0xff0000;
			txt1.width = 700;
			addChild(txt1);
			instance = this;
			NetManager.Init("192.168.1.100", 8888);
			LastEnterFrame = 0;
			this.addEventListener(Event.ENTER_FRAME, OnFrame);
		}
		public static function GetInstance():map
		{
			if (instance == null)
				instance = new map();
			return instance;
		}
		public function  OnConnected():void
		{
			txt1.text = "Event.CONNECT";
			var aUser:UserInfo = new UserInfo();
			NetManager.Socket.SendMessage(aUser);
		}
		public function  OnDisconnected():void
		{
			txt1.text = "Event.CLOSE";
		}
		public function  DoMapInfo2(aMessage:MessageBase):void
		{
			var aMapInfo2:MapInfo2;
			aMapInfo2 = MapInfo2(aMessage);
			CreateMap(aMapInfo2);
			//取玩家位置
			var aGetActorPostion:MessageBase = new MessageBase();
			aGetActorPostion.MessageType = 4;
			NetManager.Socket.SendMessage(aMapInfo2);			
		}
		public function  DoPathInfo(aMessage:MessageBase):void
		{
			var aPathInfo : PathInfo;
			aPathInfo = PathInfo(aMessage);
			AddPath(aPathInfo);
		}
		public function  DoActorsPosition(aMessage:MessageBase):void
		{
			var aActorsPosition : ActorsPosition;
			aActorsPosition = ActorsPosition(aMessage);
			AddActors(aActorsPosition);
		}
		public function  DoRemoveUser(aMessage:MessageBase):void
		{
			var aRemoveUser : RemoveUser;
			aRemoveUser = RemoveUser(aMessage);
			RemoveActor(aRemoveUser);
		}
		
		private function RemoveActor(aRemoveUser:RemoveUser):void
		{
			for (var i:int = 0; i < ActorList.length; i++)
			{
				if(ActorList[i].ActorUserInfo.UserId == aRemoveUser.UserId)
				{
					this.removeChild(ActorList[i].ActorSprite);
					ActorList = ActorList.splice(ActorList[i]);
					break;
				}
			}
		}
		
		private function CreateMap(aMapInfo:MapInfo2):void
		{
			
			MapInfo.init(aMapInfo.ColCount, aMapInfo.RowCount, aMapInfo.CellWidth, aMapInfo.CellHeight,aMapInfo.MoveSpeed);
			pan_tile=new Pan_Tile();
			addChild(pan_tile);	
			
			GetMap(aMapInfo.CellValues);
			
		}
		
		private function GetMap(MapFileName:String):void
		{
            var m_request:URLRequest = new URLRequest(MapFileName);
            var m_loader:URLLoader = new URLLoader();
            m_loader.dataFormat = URLLoaderDataFormat.BINARY;
            m_loader.addEventListener(Event.COMPLETE, onSendComplete);
			m_loader.load(m_request);
		}
        //事件，请求发送完毕
        private function onSendComplete(e:Event):void 
		{
            var m_content:ByteArray = e.target.data as ByteArray;
			
			var MapValue:String = m_content.readUTFBytes(m_content.length);
			
			pan_tile.addEventListener(MouseEvent.CLICK, MD);
			
			for (var i:int = 0; i < MapValue.length; i++) 
			{
				if (MapValue.charAt(i) == "1")
				{
					Pan_Tile.changeST(1, Pan_Tile.getCenterByPos(i));
				}
			}
			
			lib.fill_mask( MapValue, MapInfo.COLS, MapInfo.ROWS);
			
			var pt:Point = Pan_Tile.getCenterByPos(0);
			var aActor:ActorInfo = new ActorInfo();
			aActor.ActorSprite = CreateActorSprite(pt, 255 << 16);
			aActor.ActorUserInfo.UserId = 0;
			aActor.TargetPointer = pt;
			aActor.PathIndex = -1;
			SelfActor = aActor;
			this.addChild(aActor.ActorSprite);
			ActorList.push(aActor);
			
        }

		
		private function CreateActorSprite(pt:Point,cl:uint):Sprite
		{
			var aActor:Sprite = new Sprite();
			aActor.graphics.beginFill(cl);
			aActor.graphics.drawCircle(0, 0, MapInfo.HarfTile_W - 2);
			aActor.graphics.endFill();
			aActor.x = pt.x;
			aActor.y = pt.y;
			return aActor;
		}

		private function MD(e:MouseEvent):void
		{
			var pos:int = Pan_Tile.getPosByPt(stage.mouseX, stage.mouseY);
			var CurIndex:int = Pan_Tile.getPosByPt(SelfActor.TargetPointer.x, SelfActor.TargetPointer.y);
			if (pos == CurIndex)
				return;
			if (mapdt.charAt(pos) == "1" || mapdt.charAt(CurIndex) == "1")
				return;
			var FindPath:String = lib.findPath(CurIndex, pos) as String;	
			if (FindPath.length > 0)
			{
				SelfActor.Path = FindPath;
				SelfActor.PathIndex = 0;
				SelfActor.CurIndex = CurIndex;
			}

		}
		
		private function OnFrame(e:Event):void
		{
			if (LastEnterFrame == 0)
			{
				LastEnterFrame = getTimer();
				return;
			}
			var EnterFrameInterval:Number = (getTimer() - LastEnterFrame) / 1000;
			LastEnterFrame = getTimer();
			for (var i:int = 0; i < ActorList.length; i++)
			{
				MoveActor(ActorList[i],EnterFrameInterval);
			}
		}
		
		private function MoveActor(aActor:ActorInfo,EnterFrameInterval:Number):void
		{
			//是否走完一步
			if (aActor.ActorSprite.x == aActor.TargetPointer.x && aActor.ActorSprite.y == aActor.TargetPointer.y)
			{
				if (aActor.PathIndex<0 || aActor.PathIndex >= aActor.Path.length)
				{
					return;
				}
				if (aActor == SelfActor && aActor.PathIndex == 0)
				{
					//发送
					var aPathInfo:PathInfo = new PathInfo();
					aPathInfo.PathValues = SelfActor.Path;
					aPathInfo.StartIndex = SelfActor.CurIndex;
					NetManager.Socket.SendMessage(aPathInfo);

				}
				setActionSpeed(aActor);
			}
			
			if (EnterFrameInterval < MapInfo.IntervalTimeMin)
			{
				aActor.LeftTime += EnterFrameInterval;
				return;
			}
			
			if (aActor.LeftTime >= MapInfo.IntervalTimeMin)
			{
				EnterFrameInterval +=  aActor.LeftTime;
				aActor.LeftTime = 0;
			}
			var xTemp:Number = aActor.ActorSprite.x + aActor.MoveSpeedX * EnterFrameInterval;
			var yTemp:Number = aActor.ActorSprite.y + aActor.MoveSpeedY * EnterFrameInterval;
			
			var difX:Number=0;
			var difY:Number = 0;
			
			if (aActor.MoveSpeedX > 0)
			{
				difX = xTemp - aActor.TargetPointer.x
			}
			else if (aActor.MoveSpeedX < 0)
			{
				difX = aActor.TargetPointer.x - xTemp;
			}
			if (difX>0)
			{
				aActor.ActorSprite.x = aActor.TargetPointer.x;
			}
			else
			{
				aActor.ActorSprite.x = xTemp;
			}
				
			if (aActor.MoveSpeedY > 0)
			{
				difY = yTemp - aActor.TargetPointer.y
			}
			else if (aActor.MoveSpeedY < 0)
			{
				difY = aActor.TargetPointer.y - yTemp;
			}
			if (difY>0)
			{
				aActor.ActorSprite.y = aActor.TargetPointer.y;
			}
			else
			{
				aActor.ActorSprite.y = yTemp;
			}
			
			var newEnterFrameInterval :Number; 
			if (difX > 0)
			{
				newEnterFrameInterval = difX / Math.abs(aActor.MoveSpeedX);
				MoveActor(aActor, newEnterFrameInterval);
			}
			else if (difY > 0)
			{
				newEnterFrameInterval = difY / Math.abs(aActor.MoveSpeedY);
				MoveActor(aActor,newEnterFrameInterval);
			}
		}
		
		private function setActionSpeed(aActor:ActorInfo):void
		{
				//计算下一步行走方向，和行车速度
				
					var cc : String = aActor.Path.charAt(aActor.PathIndex);
					aActor.PathIndex++;
					if (cc == "0")
					{
						aActor.TargetPointer.x = aActor.ActorSprite.x;
						aActor.TargetPointer.y = aActor.ActorSprite.y + MapInfo.Tile_H;
						aActor.MoveSpeedX = 0;
						aActor.MoveSpeedY = MapInfo.MoveSpeed0;
					}
					else if (cc == "1")
					{
						aActor.TargetPointer.x = aActor.ActorSprite.x - MapInfo.HarfTile_W;
						aActor.TargetPointer.y = aActor.ActorSprite.y + MapInfo.HarfTile_H;
						aActor.MoveSpeedX = -MapInfo.MoveSpeed1;
						aActor.MoveSpeedY = MapInfo.MoveSpeed1;
					}
					else if (cc == "2")
					{
						aActor.TargetPointer.x = aActor.ActorSprite.x - MapInfo.Tile_W;
						aActor.TargetPointer.y = aActor.ActorSprite.y;
						aActor.MoveSpeedX = -MapInfo.MoveSpeed0;
						aActor.MoveSpeedY =0;
					}
					else if (cc == "3")
					{
						aActor.TargetPointer.x = aActor.ActorSprite.x - MapInfo.HarfTile_W;
						aActor.TargetPointer.y = aActor.ActorSprite.y - MapInfo.HarfTile_H;
						aActor.MoveSpeedX = -MapInfo.MoveSpeed1;
						aActor.MoveSpeedY = -MapInfo.MoveSpeed1;
					}
					else if (cc == "4")
					{
						aActor.TargetPointer.x = aActor.ActorSprite.x;
						aActor.TargetPointer.y = aActor.ActorSprite.y - MapInfo.Tile_H;
						aActor.MoveSpeedX = 0;
						aActor.MoveSpeedY = -MapInfo.MoveSpeed0;
					}
					else if (cc == "5")
					{
						aActor.TargetPointer.x = aActor.ActorSprite.x + MapInfo.HarfTile_W;
						aActor.TargetPointer.y = aActor.ActorSprite.y - MapInfo.HarfTile_H;
						aActor.MoveSpeedX = MapInfo.MoveSpeed1;
						aActor.MoveSpeedY = -MapInfo.MoveSpeed1;
					}
					else if (cc == "6")
					{
						aActor.TargetPointer.x = aActor.ActorSprite.x + MapInfo.Tile_W;
						aActor.TargetPointer.y = aActor.ActorSprite.y;
						aActor.MoveSpeedX = MapInfo.MoveSpeed0;
						aActor.MoveSpeedY =0;
					}
					else if (cc == "7")
					{
						aActor.TargetPointer.x = aActor.ActorSprite.x + MapInfo.HarfTile_W;
						aActor.TargetPointer.y = aActor.ActorSprite.y+MapInfo.HarfTile_H;
						aActor.MoveSpeedX = MapInfo.MoveSpeed1;
						aActor.MoveSpeedY = MapInfo.MoveSpeed1;
					}
		}
		
		private function AddPath(aPathInfo:PathInfo):void
		{
			var aActor:ActorInfo;
			for (var i:int = 0; i < ActorList.length; i++)
			{
				aActor = ActorList[i];
				if (aActor.ActorUserInfo.UserId == aPathInfo.UserId)
				{
					aActor.TargetPointer = Pan_Tile.getCenterByPos(aPathInfo.StartIndex);
					aActor.ActorSprite.x = aActor.TargetPointer.x;
					aActor.ActorSprite.y = aActor.TargetPointer.y;
					
					aActor.Path = aPathInfo.PathValues;
					aActor.PathIndex = 0;
					return;
				}
			}
			//增加新的。
			var pt:Point = Pan_Tile.getCenterByPos(aPathInfo.StartIndex);
			aActor = new ActorInfo();
			aActor.ActorSprite = CreateActorSprite(pt, 255);
			aActor.ActorUserInfo.UserId = aPathInfo.UserId;
			aActor.TargetPointer = pt;
			aActor.Path = aPathInfo.PathValues;
			aActor.PathIndex = 0;
			this.addChild(aActor.ActorSprite);
			ActorList.push(aActor);
		}
		
		private function AddActors(aActorsPosiont:ActorsPosition):void
		{
			for (var i:int = 0; i < aActorsPosiont.PathInfos.length; i++)
			{
				var aPathInfo:PathInfo2 = aActorsPosiont.PathInfos[i];
				var pt:Point = Pan_Tile.getCenterByPos(aPathInfo.aPathInfo.StartIndex);
				var EclipseLen:Number = (aPathInfo.EclipseTime) * MapInfo.MoveSpeed0;
				
				var aActor:ActorInfo = new ActorInfo();
				aActor.ActorSprite = CreateActorSprite(pt, 255);
				aActor.ActorUserInfo.UserId = aPathInfo.aPathInfo.UserId;
				aActor.TargetPointer = pt;
				aActor.Path = aPathInfo.aPathInfo.PathValues;
				aActor.PathIndex = 0;
				//计算当前所在位置。
				var PathLen:Number=0;
				//var EclipseTime:Number=0;
				for (var j:int = 0; j < aPathInfo.aPathInfo.PathValues.length; j++)
				{
					var cc:String = aPathInfo.aPathInfo.PathValues.charAt(j);
					if (parseInt(cc, 0) % 2 == 0)
					{
						//EclipseTime += MapInfo.Tile_H / MapInfo.MoveSpeed0;
						PathLen += MapInfo.Tile_H;
					}
					else
					{
						//EclipseTime += MapInfo.HarfTile_H / MapInfo.MoveSpeed1;
						PathLen += MapInfo.LeftDownLen;
					}
					if (PathLen >= EclipseLen)
					//if (EclipseTime >= aPathInfo.EclipseTime)
					{
						break;
					}
					setActionSpeed(aActor);
					aActor.ActorSprite.x = aActor.TargetPointer.x;
					aActor.ActorSprite.y = aActor.TargetPointer.y;
				}
				this.addChild(aActor.ActorSprite);
				ActorList.push(aActor);
			}
		}
	}
}
